package yrjdezu.abab.engineerpractice2.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import yrjdezu.abab.engineerpractice2.common.result.Result;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;

/**
 * <p>
 * 文件管理控制器
 * </p>
 *
 * @author chenke
 * @since 2025-05-23
 */
@RestController
@RequestMapping("/file")
@Api(tags = "文件管理接口")
public class FilesController {

    private static final Logger logger = LoggerFactory.getLogger(FilesController.class);

    // 文件状态常量
    private static final int STATUS_NORMAL = 1;     // 正常
    private static final int STATUS_DELETED = 0;    // 已删除(回收站)

    // 文件存储路径
    private static final String STORAGE_DIR = "storage/path";
    private static final String RECYCLE_DIR = "storage/recycle";

    // 文件元数据存储(实际项目中应使用数据库)
    private final Map<String, FileMetadata> fileMetadataMap = new HashMap<>();

    // 文件元数据类
    private static class FileMetadata {
        private String id;
        private String originalFilename;
        private String storagePath;
        private int status;
        private Date createTime;
        private Date deleteTime;

        // 构造函数、Getter和Setter方法
        public FileMetadata(String id, String originalFilename, String storagePath) {
            this.id = id;
            this.originalFilename = originalFilename;
            this.storagePath = storagePath;
            this.status = STATUS_NORMAL;
            this.createTime = new Date();
        }

        // Getter和Setter方法
        public String getId() { return id; }
        public String getOriginalFilename() { return originalFilename; }
        public String getStoragePath() { return storagePath; }
        public int getStatus() { return status; }
        public void setStatus(int status) { this.status = status; }
        public Date getCreateTime() { return createTime; }
        public Date getDeleteTime() { return deleteTime; }
        public void setDeleteTime(Date deleteTime) { this.deleteTime = deleteTime; }

        public void setStoragePath(String absolutePath) {
        }
    }

    // 文件上传接口
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> uploadFile(@RequestParam("file") MultipartFile file,
                                     @RequestParam(value = "path", defaultValue = "") String path) {
        try {
            // 文件存储逻辑
            String fileId = storeFile(file, path);
            return Result.success(fileId);
        } catch (Exception e) {
            logger.error("文件上传失败", e);
            return Result.error("文件上传失败");
        }
    }

    @GetMapping("/download/{id}")
    @ApiOperation("文件下载")
    public ResponseEntity<Resource> downloadFile(@PathVariable String id) {
        try {
            logger.info("Downloading file with ID: {}", id);

            // 验证文件存在且状态正常
            FileMetadata metadata = validateFileStatus(id, STATUS_NORMAL);

            Resource file = new FileSystemResource(metadata.getStoragePath());
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + metadata.getOriginalFilename() + "\"")
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                    .body(file);
        } catch (FileNotFoundException e) {
            logger.error("File not found with ID: {}", id, e);
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        } catch (IllegalStateException e) {
            logger.error("File status error with ID: {}", id, e);
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        } catch (Exception e) {
            logger.error("Error downloading file with ID: {}", id, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation("逻辑删除文件(移至回收站)")
    public Result<Void> deleteFile(@PathVariable String id) {
        try {
            // 验证文件存在且状态正常
            FileMetadata metadata = validateFileStatus(id, STATUS_NORMAL);

            // 更新文件状态为已删除
            metadata.setStatus(STATUS_DELETED);
            metadata.setDeleteTime(new Date());

            // 移动文件到回收站目录
            moveFileToRecycle(metadata);

            logger.info("File moved to recycle bin: {}", id);
            return Result.success();
        } catch (FileNotFoundException e) {
            logger.error("File not found with ID: {}", id, e);
            return Result.error("文件不存在");
        } catch (IllegalStateException e) {
            logger.error("File status error with ID: {}", id, e);
            return Result.error("文件状态异常，无法删除");
        } catch (Exception e) {
            logger.error("Error deleting file with ID: {}", id, e);
            return Result.error("删除文件失败");
        }
    }

    @PostMapping("/recover/{id}")
    @ApiOperation("从回收站恢复文件")
    public Result<Void> recoverFile(@PathVariable String id) {
        try {
            // 验证文件存在且状态为已删除
            FileMetadata metadata = validateFileStatus(id, STATUS_DELETED);

            // 更新文件状态为正常
            metadata.setStatus(STATUS_NORMAL);
            metadata.setDeleteTime(null);

            // 移动文件从回收站回到原目录
            moveFileFromRecycle(metadata);

            logger.info("File recovered from recycle bin: {}", id);
            return Result.success();
        } catch (FileNotFoundException e) {
            logger.error("File not found with ID: {}", id, e);
            return Result.error("文件不存在");
        } catch (IllegalStateException e) {
            logger.error("File status error with ID: {}", id, e);
            return Result.error("文件状态异常，无法恢复");
        } catch (Exception e) {
            logger.error("Error recovering file with ID: {}", id, e);
            return Result.error("恢复文件失败");
        }
    }

    @DeleteMapping("/purge/{id}")
    @ApiOperation("彻底删除文件(从回收站)")
    public Result<Void> purgeFile(@PathVariable String id) {
        try {
            // 验证文件存在且状态为已删除
            FileMetadata metadata = validateFileStatus(id, STATUS_DELETED);

            // 删除文件
            File file = new File(metadata.getStoragePath());
            if (file.exists()) {
                if (!file.delete()) {
                    throw new IOException("Failed to delete file: " + metadata.getStoragePath());
                }
            }

            // 从元数据中移除
            fileMetadataMap.remove(id);

            logger.info("File permanently deleted: {}", id);
            return Result.success();
        } catch (FileNotFoundException e) {
            logger.error("File not found with ID: {}", id, e);
            return Result.error("文件不存在");
        } catch (IllegalStateException e) {
            logger.error("File status error with ID: {}", id, e);
            return Result.error("文件状态异常，无法彻底删除");
        } catch (Exception e) {
            logger.error("Error purging file with ID: {}", id, e);
            return Result.error("彻底删除文件失败");
        }
    }

    @GetMapping("/recycle/list")
    @ApiOperation("获取回收站文件列表")
    public Result<List<Map<String, Object>>> listRecycleFiles() {
        try {
            List<Map<String, Object>> result = new ArrayList<>();

            // 过滤出状态为已删除的文件
            for (FileMetadata metadata : fileMetadataMap.values()) {
                if (metadata.getStatus() == STATUS_DELETED) {
                    Map<String, Object> fileInfo = new HashMap<>();
                    fileInfo.put("id", metadata.getId());
                    fileInfo.put("filename", metadata.getOriginalFilename());
                    fileInfo.put("deleteTime", metadata.getDeleteTime());
                    result.add(fileInfo);
                }
            }

            logger.info("Retrieved {} files from recycle bin", result.size());
            return Result.success(result);
        } catch (Exception e) {
            logger.error("Error listing recycle files", e);
            return Result.error("获取回收站文件列表失败");
        }
    }

    private String storeFile(MultipartFile file, String path) throws IOException {
        // 创建存储目录
        File dir = new File(STORAGE_DIR + (path.isEmpty() ? "" : "/" + path));
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                throw new IOException("Failed to create directory: " + dir.getAbsolutePath());
            }
        }

        // 生成唯一文件名
        String fileId = UUID.randomUUID().toString();
        String originalFilename = file.getOriginalFilename();
        String fileExtension = "";
        if (originalFilename != null) {
            int dotIndex = originalFilename.lastIndexOf('.');
            if (dotIndex > 0) {
                fileExtension = originalFilename.substring(dotIndex);
            }
        }
        String storageFilename = fileId + fileExtension;
        String storagePath = dir.getAbsolutePath() + "/" + storageFilename;

        // 保存文件
        File dest = new File(storagePath);
        file.transferTo(dest);

        // 保存文件元数据
        FileMetadata metadata = new FileMetadata(fileId, originalFilename, storagePath);
        fileMetadataMap.put(fileId, metadata);

        return fileId;
    }

    private FileMetadata validateFileStatus(String id, int expectedStatus) throws FileNotFoundException {
        FileMetadata metadata = fileMetadataMap.get(id);
        if (metadata == null) {
            throw new FileNotFoundException("File not found with ID: " + id);
        }

        if (metadata.getStatus() != expectedStatus) {
            throw new IllegalStateException("File status is not valid for this operation. ID: " + id);
        }

        return metadata;
    }

    private void moveFileToRecycle(FileMetadata metadata) throws IOException {
        // 创建回收站目录
        File recycleDir = new File(RECYCLE_DIR);
        if (!recycleDir.exists()) {
            if (!recycleDir.mkdirs()) {
                throw new IOException("Failed to create recycle directory: " + recycleDir.getAbsolutePath());
            }
        }

        // 目标文件路径
        String fileName = new File(metadata.getStoragePath()).getName();
        File destFile = new File(recycleDir, fileName);

        // 移动文件
        Files.move(
                new File(metadata.getStoragePath()).toPath(),
                destFile.toPath(),
                StandardCopyOption.REPLACE_EXISTING
        );

        // 更新元数据中的存储路径
        metadata.setStoragePath(destFile.getAbsolutePath());
    }

    private void moveFileFromRecycle(FileMetadata metadata) throws IOException {

    }
}